
package com.plug.spring;

import com.plug.common.jdbc.DBConnectionManager;
import com.plug.common.jdbc.DBConnectionPool;
import com.plug.common.spring.utils.ApplicationContextHelper;
import com.plug.common.utils.IpUtils;
import com.plug.entity.*;
import com.plug.service.*;
import com.plug.util.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Date;

import java.sql.*;
import java.util.*;


/**
 * Created by slaye on 2016/12/19.
 */

public class SpringAutoContrastTask {


    private Logger logger = LoggerFactory.getLogger(getClass());

    private DBConnectionManager dbConnectionManager = DBConnectionManager.getInstance();



   /**
     * 执行及获取配置信息；将所调方法串联
     */

    public void getToConfigure() {
        IPlugCompareTaskService plugCompareTaskService = (IPlugCompareTaskService) ApplicationContextHelper.getBean("plugCompareTaskService");
        IPlugBackupRecordService plugBackupRecordService = (IPlugBackupRecordService) ApplicationContextHelper.getBean("plugBackupRecordService");

        logger.debug("plugCompareTaskService:{},\t\tplugBackupRecordService:{}", plugCompareTaskService, plugBackupRecordService); //记录器
        List<PlugCompareTask> compareTaskList = plugCompareTaskService.findAll();  //获取所有的备份任务配置信息
        if (compareTaskList != null) {  //对比任务信息不为空！
            for (int i = 0; i < compareTaskList.size(); i++) {
                PlugBackupRecord plugBackupRecord=plugBackupRecordService.selectByBackupsAndMinuteInfo(compareTaskList.get(i).getCompareTimeQuantum(), Integer.parseInt(compareTaskList.get(i).getPlugContrastId().toString()));//查询备份记录;根据分钟数,和备份任务ID
                if(plugBackupRecord!=null){
                    this.getDataConfigure(plugBackupRecord,compareTaskList.get(i).getCompareFileds());
                }else{
                    System.out.println("空的**************************************************************************************************");
                }
            }
        }else{
            logger.debug("没有任务compareTaskList:{}",compareTaskList); //记录器
        }
    }

    /**
     * 获取要对比的数据调用对比方法
     * @param plugBackupRecord 任务对象
     * @param compareFileds  自动对比任务
     */

    private void getDataConfigure(PlugBackupRecord plugBackupRecord,String compareFileds) {

        IPlugContrastService plugContrastService = (IPlugContrastService) ApplicationContextHelper.getBean("plugContrastService");
        IPlugRecordService plugRecordService = (IPlugRecordService) ApplicationContextHelper.getBean("plugRecordService");
        IPlugDatasourceService plugDatasourceService = (IPlugDatasourceService) ApplicationContextHelper.getBean("plugDatasourceService");
        logger.debug("plugContrastService:{},\t\tplugDatasourceService:{}", plugContrastService, plugDatasourceService); //记录器


        String column = "";//用于获取或拼接对比列
        boolean isPrimaryKey=false; //用于如果要对比的列存在状态
        int toNumber=1;
        PlugOperationRecord plugOperationRecord = new PlugOperationRecord();//操作人员记录表
        PlugBackupRecord backupbRecordloger = new PlugBackupRecord();//存储对比记录
        List<PlugBackupRecord> backupbRecordlogerList=new ArrayList<>();//存储所有的对比记录
        List<PlugRecord> plugRecordList = new ArrayList<>(); //存放对比错误记录


        if (plugBackupRecord != null && compareFileds != null) {  //任务备份记录和要对比的列不为空；方可获取数据源配置再获取要对比的数据

            PlugContrast plugContrast = plugContrastService.findByID(plugBackupRecord.getPlugContrastId());//根据PlugContrastId 查询得到primaryKey
            PlugDatasource srcPlugDatasource = plugDatasourceService.findByID(plugContrast.getSrcDsId());//根据源数据库ID称查询
            PlugDatasource tgtPlugDatasource = plugDatasourceService.findByID(plugContrast.getTgtDsId());//根据备份数据库ID称查询

            //判断对比列是否有主键
            if (compareFileds.indexOf(plugContrast.getPrimaryKey())==-1){
                column =plugContrast.getPrimaryKey()+","+compareFileds; //没有就拼接
                isPrimaryKey=true;
            }else{
                column =compareFileds;
            }

            try {
                String uuid = UUID.randomUUID().toString().toUpperCase();
                //根据传入条件查询源备份数据集
                Map<String, Map<String, Object>> srcResultMap = null;
                //根据传入条件查询目标数据集
                Map<String, Map<String, Object>> tgtResultMap = null;
                //根据传入条件查询源备份数据集
                //参数有（srcPlugDatasource：源数据配置信息对象，getSrcTab：源数据表，getFromNumber：开始行，compareFileds：要对比的列，plugContrast：备份任务对象）
                srcResultMap = plugRecordService.findHistoryRecord(srcPlugDatasource,plugContrast.getSrcTab(),plugBackupRecord.getFromNumber(),plugBackupRecord.getToNumber(),column,plugContrast);
                //根据传入条件查询目标数据集
                tgtResultMap = plugRecordService.findHistoryRecord(tgtPlugDatasource,plugContrast.getTgtTab(),plugBackupRecord.getFromNumber(),plugBackupRecord.getToNumber(),column,plugContrast);


                //源数据组装及对比
                for (String key : srcResultMap.keySet()){
                    //toNumber=toNumber+1;
                    Map<String, Object> srcMap = srcResultMap.get(key);
                    Map<String, Object> tgtMap = tgtResultMap.get(key);
                    String srcData = "";//行源数据
                    String tgtData = "";//行目标数据
                    String srcColumn = "";
                    String tgtColumn = "";

                    if(!tgtResultMap.containsKey(key)) {
                        for(String str : srcMap.keySet()) {

                            if(isPrimaryKey){//任务中对比列没有PrimaryKey
                                if(!str.equals(plugContrast.getPrimaryKey())){//排除手动添加的PrimaryKey
                                    System.out.println("*********************************************************************打印列str："+str);
                                    srcColumn += str + ",&,";
                                    tgtColumn += str + ",&,";
                                    tgtData += "    ,&,    ";
                                    srcData += StringUtils.convertString(srcMap.get(str));
                                    srcData += ",&,";
                                }
                            }else{ //任务中有PrimaryKey
                                srcColumn += str + ",&,";
                                tgtColumn += str + ",&,";
                                tgtData += "    ,&,    ";
                                srcData += StringUtils.convertString(srcMap.get(str));
                                srcData += ",&,";
                            }
                        }
                    }

                    /*if(str.equals(plugContrast.getPrimaryKey())){
                            toNumber=Integer.parseInt(StringUtils.convertString(tgtMap.get(str)));
                            if(toNumber<Integer.parseInt(StringUtils.convertString(tgtMap.get(str)))){
                                toNumber=Integer.parseInt(StringUtils.convertString(tgtMap.get(str)));
                            }
                        }
                    }*/

                    //数据对比
                    if(!srcData.equals(tgtData)){
                        PlugRecord pl = new PlugRecord();
                        pl.setCreatetime(new Date());
                        pl.setSrcDesc(srcData);
                        pl.setTgtDesc(tgtData);
                        pl.setSrcColumn(srcColumn);
                        pl.setTgtColumn(tgtColumn);
                        pl.setCrId(uuid);
                        System.out.println("对比有错误数据**A*****************************tgtData："+srcData+"*******************************tgtData"+tgtData);
                        plugRecordList.add(pl);
                    }
                }

                //备份数据组装及对比
                for (String key : tgtResultMap.keySet()){
                    Map<String, Object> srcMap = srcResultMap.get(key);
                    Map<String, Object> tgtMap = tgtResultMap.get(key);
                    String srcData = "";//行源数据
                    String tgtData = "";//行目标数据
                    String srcColumn = "";
                    String tgtColumn = "";

                    if(srcResultMap.containsKey(key)) {
                        for(String str : tgtMap.keySet()) {
                            if(isPrimaryKey) {//任务中对比列没有PrimaryKey
                                if (!str.equals(plugContrast.getPrimaryKey())) {//排除手动添加的PrimaryKey

                                    System.out.println("*********************************************************************遍历str："+str);
                                    srcColumn += str + ",&,";
                                    tgtColumn += str + ",&,";
                                    srcData += StringUtils.convertString(srcMap.get(str));
                                    srcData += ",&,";
                                    tgtData += StringUtils.convertString(tgtMap.get(str));
                                    tgtData += ",&,";
                                }
                            }else{
                                srcColumn += str + ",&,";
                                tgtColumn += str + ",&,";
                                srcData += StringUtils.convertString(srcMap.get(str));
                                srcData += ",&,";
                                tgtData += StringUtils.convertString(tgtMap.get(str));
                                tgtData += ",&,";
                            }
                        }
                    } else {
                        for(String str : tgtMap.keySet()) {
                            if(isPrimaryKey) {//任务中对比列没有PrimaryKey
                                if (!str.equals(plugContrast.getPrimaryKey())) {//排除手动添加的PrimaryKey

                                    srcColumn += str + ",&,";
                                    tgtColumn += str + ",&,";
                                    srcData += "    ,&,    ";
                                    tgtData += StringUtils.convertString(tgtMap.get(str));
                                    tgtData += ",&,";
                                }
                            }else{
                                srcColumn += str + ",&,";
                                tgtColumn += str + ",&,";
                                srcData += "    ,&,    ";
                                tgtData += StringUtils.convertString(tgtMap.get(str));
                                tgtData += ",&,";
                            }

                        }
                    }
                    //数据对比
                    if(!srcData.equals(tgtData)){
                        System.out.println("对比有错误数据**B*****************************tgtData："+srcData+"*******************************tgtData"+tgtData);
                        PlugRecord pl = new PlugRecord();
                        pl.setCreatetime(new Date());
                        pl.setSrcDesc(srcData);
                        pl.setTgtDesc(tgtData);
                        pl.setSrcColumn(srcColumn);
                        pl.setTgtColumn(tgtColumn);
                        pl.setCrId(uuid);
                        plugRecordList.add(pl);
                    }
                }

                //组装操作人员记录
                plugOperationRecord.setId(uuid);
                plugOperationRecord.setCreatetime(new Date());
                StringBuffer desc = new StringBuffer("数据源库名："+srcPlugDatasource.getDsName()+",备份名："+tgtPlugDatasource.getDsName()+";");
                desc.append("数据源表名："+plugContrast.getSrcTab()+",备份表名名："+plugContrast.getTgtTab()+";");
                desc.append("本次对比共有："+plugRecordList.size()+"条数据不一致；");
                plugOperationRecord.setDescs(desc.toString());
                plugOperationRecord.setCtId(plugBackupRecord.getPlugContrastId());

                //组装对比记录
                backupbRecordloger.setActionType("自动对比记录");//记录方式
                backupbRecordloger.setSrcDatabase(plugBackupRecord.getSrcDatabase()); //源数据库
                backupbRecordloger.setSrcTable(plugBackupRecord.getSrcTable()); //源数据库表
                backupbRecordloger.setTgtDatabase(plugBackupRecord.getTgtDatabase());//备份数据库
                backupbRecordloger.setTgtTable(plugBackupRecord.getTgtTable());//备份数据库表
                backupbRecordloger.setPlugContrastId(plugBackupRecord.getPlugContrastId()); //备份任务配置表ID
                backupbRecordloger.setCreateTime(new Date());//创建时间
                backupbRecordloger.setState(0);//状态0表示成功
                backupbRecordloger.setMessage("自动对比" + plugBackupRecord.getTgtTable() + "数据完成");
                backupbRecordloger.setFromNumber(plugBackupRecord.getFromNumber());
                backupbRecordloger.setToNumber(plugBackupRecord.getToNumber());
                backupbRecordlogerList.add(backupbRecordloger);
                //调用对比记录保存方法
                this.ContrastMethod(plugRecordList,plugOperationRecord,backupbRecordlogerList);

            }catch (Exception e){
                logger.error("对比任务异常："+e);
            }
        }
    }

    /**
     * 数据对比及保存对比后数据
     * @param recordList 存储错误记录
     * @param plugOperationRecord 存储操作人记录
     * @param backupbRecordlogerList 存储对比全部记录
     */
    private void ContrastMethod(List<PlugRecord> recordList, PlugOperationRecord plugOperationRecord, List<PlugBackupRecord> backupbRecordlogerList) throws Exception {

        IPlugBackupRecordService plugBackupRecordService = (IPlugBackupRecordService) ApplicationContextHelper.getBean("plugBackupRecordService");
        IPlugRecordService iPlugRecordService = (IPlugRecordService) ApplicationContextHelper.getBean("plugRecordService");
        logger.debug("iPlugRecordService:{},plugBackupRecordService:{}", iPlugRecordService,plugBackupRecordService); //记录器


            //获得本机IP
            try {
                InetAddress addr = InetAddress.getLocalHost();
                plugOperationRecord.setOperationip(addr.getHostAddress().toString());
            } catch (UnknownHostException e) {
                logger.error("对比任务获得本机IP异常："+e);
            }
            //保存自动对比记录
            if(backupbRecordlogerList!=null){
                int backup=plugBackupRecordService.saveBatch(backupbRecordlogerList);//调用保存对比记录方法
                if(backup==backupbRecordlogerList.size()){
                    logger.debug("保存自动对比记录backup:{}",backup );
                }
            }
            // 将（对比记录信息）and(操作人员记录)保存错误信息；
            if(recordList!=null && recordList.size() > 0 && plugOperationRecord!=null){  //有错误对比数据
                int count= iPlugRecordService.saveRecordAndOperation(recordList,plugOperationRecord); //调用自动对比记录保存方法
                if(count>0){
                    logger.debug("过程成功count:{}",count );
                }else{
                    logger.error("将（对比记录信息）and(操作人员记录)保存错误信息；"+count+"受影响");
                }
            }else{
                System.out.println("\n\t*************************************************"+new Date()+"第批次；没有错误记录**********recordList.size："+recordList.size()+"****************************************\n");
            }
    }
}

